package com.lelouch.examplecode.designpattern.proxy.dynamic.jdk;

import com.lelouch.examplecode.designpattern.proxy.staticd.Person;
import com.lelouch.examplecode.designpattern.proxy.staticd.Son;
import sun.misc.ProxyGenerator;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;


/**
 * @author lcy
 * @create 2018-10-10 14:18
 */
public class DynamicProxyTest {
    public static void main(String[] args) throws IOException {
        Person person = new Son();

        //原理：
        //1、拿到被代理对象的引用，并且获取到它的所有的接口，反射获取
        //2、JDK Proxy类重新生成一个新的类、同时新的类要实现被代理类所有实现的所有的接口
        //3、动态生成Java代码，把新加的业务逻辑方法由一定的逻辑代码去调用（在代码中体现）
        //4、编译新生成的Java代码.class
        //5、再重新加载到JVM中运行
        //以上这个过程就叫字节码重组

        //JDK中有个规范，只要要是$开头的一般都是自动生成的

        //通过反编译工具可以查看源代码


        //ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
        //Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
        //InvocationHandler:指定动态处理器，执行目标对象的方法时,会触发事件处理器的方法
        Person proxyPerson = (Person) Proxy.newProxyInstance(Son.class.getClassLoader(), new Class[]{Person.class}, new DynamicProxyHandler(person));
        proxyPerson.findLove();
        proxyPerson.rentHouse();
      //  System.out.println(proxyPerson.getClass());
        System.out.println(proxyPerson);


        //byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
        //FileOutputStream fileOutputStream = new FileOutputStream(new File("E://$proxy0.class"));
        //
        //fileOutputStream.write(bytes);

    }
}
